
package com.study.manage.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * 字符串工具类
 * 
 * @version 1.0 2017/9/5
 */
public class CmnStringUtils extends StringUtils {

    /** 空字符串 */
    public static final String EMPTY = "";

    /** 空格 */
    public static final String HALF_SPACE = " ";

    /** JSON缩进字符 */
    public static final String JSON_FORMAT_FILL_STRING_UNIT = "    ";

    /** 大于号字符 */
    public static final String BIG_SYMBOL = ">";

    /** 小于号字符 */
    public static final String SMALL_SYMBOL = "<";

    /** 大于号网页显示字符 */
    public static final String HTML_BIG_SYMBOL = "&gt;";

    /** 小于号网页显示字符 */
    public static final String HTML_SMALL_SYMBOL = "&lt;";

    /** HTML换行 */
    public static final String HTML_BR = "<br>";

    /** Textarea换行 */
    public static final String TEXTAREA_BR = "\r\n";

    /**
     * 把没有实例化的串转化为空串
     * 
     * @param str String
     * @return String
     */
    public static String convertNull(String str) {

        if (str == null){
            return "";
        }else{
            return str;
        }
    }

    /**
     * 把没有实例化的长整形转化为空串(用于显示日期)
     * 
     * @param date String
     * @return String
     */
    public static String convertNull(Integer date) {

        if (date == null){
            return "";
        }else{
            return date.toString();
        }
    }

    /**
     * 把没有实例化的长整形转化为空串
     * 
     * @param str String
     * @return String
     */
    public static String convertNull(Long str) {

        if (str == null){
            return "";
        }else{
            return str.toString();
        }
    }

    /**
     * 把没有实例化的对象转化为空串
     * 
     * @param obj String
     * @return String
     */
    public static String convertNull(Object obj) {

        if (obj == null){
            return "";
        }else{
            return obj.toString();
        }
    }

    /**
     * 把空字符串转化为null
     * 
     * @param str String
     * @return String
     */
    public static String convertEmpty(String str) {

        if (isEmpty(str)){
            return null;
        }else{
            return str;
        }
    }

    /**
     * 把空白字符串转化为null
     * 
     * @param str String
     * @return String
     */
    public static String convertBlank(String str) {

        if (isBlank(str)){
            return null;
        }else{
            return str;
        }
    }

    /**
     * 控制页面显示长度,dataStr为控制长度的字符串，length为字节的长度；
     * 字符串的字节长度小于显示长度，则原样输出，否则以XXX...的形式输出。
     * 
     * @param dataStr String
     * @param length int
     * @return String
     */
    public static String controlLength(String dataStr, int length) {

        if (dataStr == null){
            return "";
        }
        // 转化成格式化的Html
        dataStr = escape(dataStr);

        StringBuffer sb = new StringBuffer();
        char datach;
        int lengthi = 0; // 字符串的字节长度
        int strj = 0; // 字符串的实际长度
        int lengthi3 = 0; // 字节长度-4
        // 得到字符串的字节长度
        while (strj < dataStr.length()){
            datach = dataStr.charAt(strj++);
            if (((datach <= 'z') && (datach >= 'a'))
                || ((datach <= 'Z') && (datach >= 'A'))
                || ((datach <= '9') && (datach >= '0'))){
                lengthi++;
            }else{
                lengthi = lengthi + 2;
            }
        }
        strj = 0;
        // 得到字符串的字节长度-4
        while ((lengthi3 < length - 4) && (strj < dataStr.length())){
            datach = dataStr.charAt(strj++);
            sb.append(datach);
            if (((datach <= 'z') && (datach >= 'a'))
                || ((datach <= 'Z') && (datach >= 'A'))
                || ((datach <= '9') && (datach >= '0'))){
                lengthi3++;
            }else{
                lengthi3 = lengthi3 + 2;
            }
        }
        if (lengthi <= length){
            return dataStr;
        }else{
            sb.append("...");
        }
        return sb.toString();
    }

    /**
     * 把HTML字符串转化成普通字符串
     * 
     * @param html
     * @return
     */
    public static String unescape(String html) {

        if (html == null){
            return EMPTY;
        }
        // &amp; - > &
        html = html.replaceAll("&[Aa][Mm][Pp];", "&");
        // &nbsp; - > " "
        html = html.replaceAll("&[nN][bB][sS][pP];", " ");
        // <br> - > \n
        html = html.replaceAll("<[bB][rR]\\s*>", "\n");
        // $$ - > $
        html = html.replaceAll("\\$\\$", "\\$");
        // &gt; - > >
        html = html.replaceAll("&[gG][tT];", ">");
        // &lt; - > <
        html = html.replaceAll("&[lL][tT];", "<");
        // &quot; - > \
        html = html.replaceAll("&[qQ][Uu][Oo][Tt];", "\\");

        return html;
    }

    /**
     * 把字符串转化成HTML字符串
     * 
     * @param str --需要转换的字符串
     * @return String --返回把特殊字符转换了的字符串
     */
    public static String escape(String str) {

        if (str == null){
            return "";
        }
        byte[] data = str.getBytes();
        int len = data.length;
        StringBuffer result = new StringBuffer(len * 2);

        int begin = 0, count = 0;
        for (int i = 0; i < len; i++){
            switch ((char) data[i]) {
                case '&':
                    result.append(new String(data, begin, count));
                    result.append("&amp;");
                    begin = i + 1;
                    count = 0;
                    break;
                case '\"':
                    result.append(new String(data, begin, count));
                    result.append("&quot;");
                    begin = i + 1;
                    count = 0;
                    break;
                case '<':
                    result.append(new String(data, begin, count));
                    result.append("&lt;");
                    begin = i + 1;
                    count = 0;
                    break;
                case '>':
                    result.append(new String(data, begin, count));
                    result.append("&gt;");
                    begin = i + 1;
                    count = 0;
                    break;
                case '\n':
                    result.append(new String(data, begin, count));
                    result.append("<br>");
                    begin = i + 1;
                    count = 0;
                    break;
                case '$':
                    result.append(new String(data, begin, count));
                    result.append("$$");
                    begin = i + 1;
                    count = 0;
                    break;
                case ' ':
                    result.append(new String(data, begin, count));
                    result.append("&nbsp;");
                    begin = i + 1;
                    count = 0;
                    break;
                default:
                    count++;
                    break;
            }
        }
        if (count > 0){
            result.append(new String(data, begin, count));
        }
        return result.toString();
    }

    /**
     * 将textarea输入的文本转化成前台html显示的格式，主要将回车（/r/n）替换成<br>
     * ," "替换成&nbsp;
     * 
     * @param text String
     * @return String
     */
    public static String textConvertToHtmlText(String text) {

        if (text != null){
            return text.replaceAll("\r\n", "<br>").replaceAll(" ", "&nbsp;");
        }else{
            return null;
        }
    }

    /**
     * 输入带html标签的字符串,返回干净的字符串,其中将(&nbsp;->" "),(<br>
     * ->\r\n),(
     * <p>
     * ->\r\n\r\n)
     * 
     * @param html body String
     * @return String
     */
    public static String htmlTextConvertToText(String html) {

        // 替换&nbsp;->" ",<br>->\r\n <p>->\r\n\r\n
        html = html.replaceAll("&[nN][bB][sS][pP];", " ");
        html = html.replaceAll("<[bB][rR]\\s*>", "\r\n");
        html = html.replaceAll("<[pP]\\s*>", "\r\n\r\n");
        // 删除所有标签

        html = html.replaceAll("<.+?>", EMPTY);
        return html;
    }

    /**
     * 全数字判断
     * 
     * @param strIn String
     * @return boolean
     */
    public static boolean isNumberString(String strIn) {

        return isNumberString(strIn, "0123456789");
    }

    /**
     * 全数字判断,参照字符串strRef可以是:"0123456789","23546"或"0123"等等。
     * 
     * @param strIn String
     * @param strRef String
     * @return boolean
     */
    public static boolean isNumberString(String strIn, String strRef) {

        if (strIn == null || strIn.length() == 0){
            return (false);
        }
        for (int i = 0; i < strIn.length(); i++){
            String strTmp = strIn.substring(i, i + 1);
            if (strRef.indexOf(strTmp, 0) == -1){
                return (false);
            }
        }
        return (true);
    }

    /**
     * 字符串替换,调用了org.apache.commons.lang.StringUtils.replace()
     * 
     * @param strObj 目标字符串
     * @param str1 被替换的字符串
     * @param str2 替换成的字符串
     * @return String
     */
    public static String replace(String strObj, String str1, String str2) {

        if ("".equals(str1)){
            return strObj;
        }
        return StringUtils.replace(strObj, str1, str2);
    }

    /**
     * 根据内容生成摘要
     * 
     * @param content String
     * @return String
     */
    public static String createSummary(String content) {

        if (content == null){
            return null;
        }
        String regexp = "<.*?>";
        // System.out.println(regexp);
        content = content.replaceAll(regexp, "");
        int len = content.length();
        if (len > 120){
            return content.substring(0, 120);
        }else{
            return content;
        }
    }

    /**
     * 用于转义单斜杠特殊字符
     * 
     * @param str String
     * @return String
     */
    public static final String appendStr(String str) {

        char c = ' ';
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str.length(); i++){
            c = str.charAt(i);
            if (c == '\\'){
                sb.append("\\\\");
            }else{
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 将reader流中的数据变成String
     * 
     * @param is reader流
     * @return String
     * @throws IOException 异常
     */
    public static String readerToString(Reader is) throws IOException {

        StringBuffer sb = new StringBuffer();
        char[] b = new char[8192];
        int n;
        while ((n = is.read(b)) > 0){
            sb.append(b, 0, n);
        }
        return sb.toString();
    }

    /**
     * 将input流中的数据变成String
     * 
     * @param is InputStream流
     * @throws IOException 异常
     * @return String
     */
    public static String inputStreamToString(InputStream is) throws IOException {

        return readerToString(new InputStreamReader(is));
    }

    /**
     * 返回字符串的前len个字符.例如:输入"abcdefg",3 返回 "abc".
     * 
     * @param value String
     * @param len int
     * @return String
     */
    public static String getLmtStr(String value, int len) {

        if (value == null || value.length() <= len){
            return value;
        }
        return value.substring(0, len);
    }

    /**
     * 返回字符串的前len个字符.例如:输入"abcdefg",3 返回 "abc...".
     * 
     * @param value String
     * @param len int
     * @return String
     */
    public static String getLmtString(String value, int len) {

        if (value == null || value.length() <= len){
            return value;
        }
        return value.substring(0, len) + "...";
    }

    /**
     * 输入带html标签的字符串,返回干净的字符串,其中将(&nbsp;->" "),(<br>
     * ->\r\n),(
     * <p>
     * ->\r\n\r\n)
     * 
     * @param body String
     * @return String
     */
    public static String getCleanString(String body) {

        // 替换&nbsp;->" ",<br>->\r\n <p>->\r\n\r\n
        body = body.replaceAll("&[nN][bB][sS][pP];", " ");
        body = body.replaceAll("<[bB][rR]\\s*>", "\r\n");
        body = body.replaceAll("<[pP]\\s*>", "\r\n\r\n");
        // 删除所有标签

        body = body.replaceAll("<.+?>", "");
        return body;

    }

    /**
     * 返回字符串的len个字符.取前后，去掉中间 例如:输入"abcdefg",3 返回 "ab ... g".
     * 
     * @param value String
     * @param len int
     * @return String
     */
    public static String getLmtStrx(String value, int len) {

        if (value == null || value.length() <= len){
            return value;
        }
        value = value.substring(0, len / 2) + ".."
            + value.substring(value.length() - len / 2);
        return value;
    }

    /**
     * 给传入的字符串前补足'0'，以使字符串长度为len。例如：输入字符串:"23",4 返回:"0023"。
     * 
     * @param str String
     * @param len int
     * @return String
     */
    public static String getZeroStr(String str, int len) {

        int strlen = str.length();
        for (int i = 0; i < len - strlen; i++){
            str = "0" + str;
        }
        return str;
    }

    /**
     * 如果时间为空 则返回空 如果不足6位 左补零
     * 
     * @param time 时间
     * @return 文字列
     */
    public static String getZeroTime(Integer time) {

        String timeStr = convertNull(time);
        if (timeStr.length() != 0 && timeStr.length() != 6){
            timeStr = getZeroStr(timeStr, 6);
        }

        return timeStr;
    }

    /**
     * [ab][cd] , - > ab,cd
     * 
     * @param array String[]
     * @param split char
     * @return String
     */
    public static String getArrayAsString(String[] array, char split) {

        String rs = "";
        if (array != null){
            for (int i = 0; i < array.length; i++){
                rs += array[i];
                if (i != array.length - 1){
                    rs += split;
                }
            }
        }
        return rs;
    }

    /**
     * [ab][cd] , - > ab,cd
     * 
     * @param list List<String>
     * @param split char
     * @return String
     */
    public static String getListAsString(List<String> list, char split) {

        String rs = "";
        if (list != null){
            for (int i = 0; i < list.size(); i++){
                rs += list.get(i);
                if (i != list.size() - 1){
                    rs += split;
                }
            }
        }
        return rs;
    }

    /**
     * 过滤HTML标签
     * 
     * @param value String
     * @return String
     */
    public static String filterScriptHtml(String value) {

        if (value == null){
            return "";
        }else{
            value = value.replaceAll("<", "&lt;");
            value = value.replaceAll(">", "&gt;");
        }
        return value;
    }

    /**
     * @param value double
     * @param format String "0.00"
     * @return String
     */
    public static String getFormatDouble(double value, String format) {

        DecimalFormat d = new DecimalFormat(format);
        return d.format(value);
    }

    /**
     * 0.34567 -> 0.35
     * 
     * @param value double
     * @return String
     */
    public static String getFormatDouble(double value) {

        return getFormatDouble(value, "0.00");
    }

    /**
     * 判断str是否在src String[]中
     * 
     * @param src 源String[]
     * @param str 要判断的String
     * @return boolean
     */
    public static boolean isContain(String[] src, String str) {

        if (null == src){
            return false;
        }
        for (int i = 0; i < src.length; i++){
            if (str.equalsIgnoreCase(src[i])){
                return true;
            }
        }
        return false;
    }

    /**
     * 产生一个随机id,这个id以系统时间开头
     * 
     * @return String
     */
    public static String createId() {

        // System.out.println(System.currentTimeMillis());
        String c = "" + getCount();
        if (c.length() == 1){
            c = "0" + c;
        }
        String id = System.currentTimeMillis() + c;
        int len = 32 - id.length();

        return id + RandomStringUtils.randomAlphanumeric(len);
    }

    /** 计数 */
    private static int counter = 0;

    /**
     * 
     * 取得当前数字
     * 
     * @return 1- 99的数字
     * */
    protected static int getCount() {

        synchronized (StringUtils.class){
            if (counter < 0){
                counter = 0;

            }
            counter++;
            if (counter == 99){
                counter = 0;
            }
            return counter;
        }
    }

    /**
     * 
     * 去除字符串前面的指定字符
     * 
     * @param str 元字符
     * @param stripChars 指定字符
     * @return 处理后字符
     */
    public static String stripStart(String str, String stripChars) {

        if (isEmpty(str)){
            return str;
        }

        int strLen = str.length();
        int start = 0;
        if (stripChars == null){
            while ((start != strLen)
                && Character.isWhitespace(str.charAt(start))){
                start++;
            }
        }else if (stripChars.length() == 0){
            return str;
        }else{
            while ((start != strLen)
                && (stripChars.indexOf(str.charAt(start)) != -1)){
                start++;
            }
        }
        return str.substring(start);
    }

    /**
     * 
     * 去除指定字符的后面的特定字符
     * 
     * @param str 元字符
     * @param stripChars 指定字符
     * @return 处理后字符
     */
    public static String stripEnd(String str, String stripChars) {

        if (isEmpty(str)){
            return str;
        }
        int end = str.length();
        if (stripChars == null){
            while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))){
                end--;
            }
        }else if (stripChars.length() == 0){
            return str;
        }else{
            while ((end != 0)
                && (stripChars.indexOf(str.charAt(end - 1)) != -1)){
                end--;
            }
        }
        return str.substring(0, end);
    }

    /**
     * 
     * 去除字符串前面的指定前缀字符
     * 
     * @param str 元字符
     * @param stripStr 指定前缀字符
     * @return 处理后字符
     */
    public static String subPrefixStr(String str, String stripStr) {

        if (isEmpty(str)){
            return str;
        }

        int strLen = str.length();
        int start = 0;
        if (stripStr == null){
            while ((start != strLen)
                && Character.isWhitespace(str.charAt(start))){
                start++;
            }
        }else if (stripStr.length() == 0){
            return str;
        }else if (indexOf(str, stripStr) >= 0){
            start = stripStr.length();
        }
        return str.substring(start);
    }

    /**
     * 
     * 
     * 包装原始字符串的indexOf加上相应处理
     * 
     * @param str 元字符
     * @param searchStr 查询字符
     * @return int 返回类型
     */
    public static int indexOf(String str, String searchStr) {

        if (str == null || searchStr == null){
            return -1;
        }
        return str.indexOf(searchStr);
    }

    /**
     * 
     * 
     * 返回特定字符的前面的字符
     * <p>
     * StringUtils.substringBefore(null, *) = null
     * StringUtils.substringBefore("", *) = ""
     * StringUtils.substringBefore("abc", "a") = ""
     * StringUtils.substringBefore("abcba", "b") = "a"
     * StringUtils.substringBefore("abc", "c") = "ab"
     * StringUtils.substringBefore("abc", "d") = "abc"
     * StringUtils.substringBefore("abc", "") = ""
     * StringUtils.substringBefore("abc", null) = "abc"
     * 
     * @param str 元字符
     * @param separator 指定字符
     * 
     * @return 取得字符
     */
    public static String substringBefore(String str, String separator) {

        if (isBlank(str) || separator == null){
            return str;
        }
        if (separator.length() == 0){
            return EMPTY;
        }
        int pos = str.indexOf(separator);
        if (pos == -1){
            return str;
        }
        return str.substring(0, pos);
    }

   

    /**
     * Json格式化
     * 
     * @param json 字符串数据
     * @return Json格式化字符串
     */
    public static String jsonFormatOutPut(String json) {

        if (isBlank(json)){
            return "";
        }
        String fillStringUnit = CmnStringUtils.JSON_FORMAT_FILL_STRING_UNIT;
        int fixedLenth = 0;
        ArrayList<String> tokenList = new ArrayList<String>();
        String jsonTemp = json;
        // 预读取
        while (jsonTemp.length() > 0){
            String token = getToken(jsonTemp);
            jsonTemp = jsonTemp.substring(token.length());
            token = token.trim();
            tokenList.add(token);
        }

        for (int i = 0; i < tokenList.size(); i++){
            String token = tokenList.get(i);
            int length = token.getBytes().length;
            if (length > fixedLenth && i < tokenList.size() - 1
                && tokenList.get(i + 1).equals(":")){
                fixedLenth = length;
            }
        }

        StringBuilder buf = new StringBuilder();
        int count = 0;
        for (int i = 0; i < tokenList.size(); i++){

            String token = tokenList.get(i);

            if (token.equals(",")){
                buf.append(token);
                doFill(buf, count, fillStringUnit);
                continue;
            }
            if (token.equals(":")){
                buf.append(" ").append(token).append(" ");
                continue;
            }
            if (token.equals("{")){
                String nextToken = tokenList.get(i + 1);
                if (nextToken.equals("}")){
                    i++;
                    buf.append("{ }");
                }else{
                    count++;
                    buf.append(token);
                    doFill(buf, count, fillStringUnit);
                }
                continue;
            }
            if (token.equals("}")){
                count--;
                doFill(buf, count, fillStringUnit);
                buf.append(token);
                continue;
            }
            if (token.equals("[")){
                String nextToken = tokenList.get(i + 1);
                if (nextToken.equals("]")){
                    i++;
                    buf.append("[ ]");
                }else{
                    count++;
                    buf.append(token);
                    doFill(buf, count, fillStringUnit);
                }
                continue;
            }
            if (token.equals("]")){
                count--;
                doFill(buf, count, fillStringUnit);
                buf.append(token);
                continue;
            }

            buf.append(token);
            // 左对齐
            if (i < tokenList.size() - 1 && tokenList.get(i + 1).equals(":")){
                int fillLength = fixedLenth - token.getBytes().length;
                if (fillLength > 0){
                    for (int j = 0; j < fillLength; j++){
                        buf.append(" ");
                    }
                }
            }
        }
        return buf.toString();
    }

    /**
     * json格式化: getToken
     * 
     * @param json Json字符串
     * @return token
     */
    private static String getToken(String json) {

        StringBuilder buf = new StringBuilder();
        boolean isInYinHao = false;
        while (json.length() > 0){
            String token = json.substring(0, 1);
            json = json.substring(1);

            if (!isInYinHao
                && (token.equals(":") || token.equals("{") || token.equals("}")
                    || token.equals("[") || token.equals("]") || token
                        .equals(","))){
                if (buf.toString().trim().length() == 0){
                    buf.append(token);
                }

                break;
            }

            if (token.equals("\\")){
                buf.append(token);
                buf.append(json.substring(0, 1));
                json = json.substring(1);
                continue;
            }
            if (token.equals("\"")){
                buf.append(token);
                if (isInYinHao){
                    break;
                }else{
                    isInYinHao = true;
                    continue;
                }
            }
            buf.append(token);
        }
        return buf.toString();
    }

    /**
     * 换行缩进
     * 
     * @param buf buf
     * @param count count
     * @param fillStringUnit fillStringUnit
     */
    private static void doFill(StringBuilder buf, int count,
        String fillStringUnit) {

        buf.append("\n");
        for (int i = 0; i < count; i++){
            buf.append(fillStringUnit);
        }
    }

    /**
     * 日期的默认格式转换。
     * 
     * @param target 日期文字列
     * @param reg 日期文字列
     * @param to 日期文字列
     * @return "yyyyMMdd"形式
     */
    public static String replaceAll(String target, String reg, String to) {

        if (target == null){
            return target;
        }
        return target.replaceAll(reg, to);
    }

    /**
     * 日期的默认格式转换。
     * 
     * @param target 日期文字列
     * @param reg 日期文字列
     * @return "yyyyMMdd"形式
     */
    public static String replaceAllToEmpty(String target, String reg) {

        return replaceAll(target, reg, EMPTY);
    }

    /**
     * 增加百分号
     * 
     * @param data 日期文字列
     * @return data%
     */
    public static String addPercent(Object data) {

        String sourceStr = CmnStringUtils.convertNull(data);
        if (CmnStringUtils.isBlank(sourceStr)){
            return CmnStringUtils.EMPTY;
        }
        return sourceStr + "%";
    }

    /**
     * 参数替换
     * 
     * @param target 目标文字
     * @param params 参数
     * @return 替换后文字
     */
    public static String replaceParam(String target, String... params) {

        MessageFormat form = new MessageFormat(target);

        return form.format(params);
    }

    /**
     * 将小于号和大于号转为转义字符
     * 
     * @param str 变换前的字符串
     * @return 变换后的字符串
     */
    public static String encodeLtGt(String str) {

        if (str == null || str.length() == 0){
            return EMPTY;
        }
        return str.replaceAll(SMALL_SYMBOL, HTML_SMALL_SYMBOL).replaceAll(
            BIG_SYMBOL, HTML_BIG_SYMBOL);
    }

    /**
     * 判断是否为空字符串
     * 
     * @param cs String
     * @return 非空为true
     */
    public static boolean isNotEmpty(String cs) {

        if (cs == null){
            return false;
        }else{
            return StringUtils.isNotEmpty(cs);
        }
    }
    
    /**
     * 将空字符串转化为null
     * 
     * @param cs String
     * @return null;
     */
    public static String emptyToNull(String cs) {
        //判断是否为空字符串
        if(isBlank(cs)){
            return null;
        }
        return cs;
    }
}
